package com.huidu.bitrade.controller.analytics;


import com.huidu.bitrade.controller.common.BaseAdminController;
import com.huidu.bitrade.entity.QExchangeCoin;
import com.huidu.bitrade.mapper.ExchangeOrderMapper;
import com.huidu.bitrade.mapper.MemberWalletMapper;
import com.huidu.bitrade.model.vo.CoinBalanceQO;
import com.huidu.bitrade.model.vo.PendingOrderQO;
import com.huidu.bitrade.model.vo.R;
import com.huidu.bitrade.model.vo.WarehouseQO;
import com.huidu.bitrade.service.ExchangeCoinService;
import com.huidu.bitrade.util.DateUtil;
import com.huidu.bitrade.util.PredicateUtils;
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.BooleanExpression;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Objects;


@RequestMapping("analytics")
@RestController
public class AnalyticsController extends BaseAdminController {

    private final RestTemplate restTemplate = new RestTemplate();
    @Value("${admin.url}")
    private String adminUrl;
    @Autowired
    private ExchangeCoinService exchangeCoinRepository;

    @Autowired
    private MemberWalletMapper memberWalletMapper;

    @Autowired
    private ExchangeOrderMapper exchangeOrderMapper;

    @Value("${spark.system.md5.key}")
    private String token;

    @ApiOperation(value = "每日统计查询")
    @GetMapping(value = "/dailyStatistics")
    public R getBalance(CoinBalanceQO page) {
        String url = adminUrl + "/system/daily/query/balance?";
        StringBuffer stringBuffer = new StringBuffer(url);
        entitySuperclassToUrlParam(page, CoinBalanceQO.class, stringBuffer);
        return restTemplate.getForEntity(stringBuffer.toString(), R.class).getBody();
    }

    @ApiOperation(value = "获取交易对")
    @GetMapping(value = "/findContractCoin")
    public R findContractCoin(@RequestParam(value = "symbol", required = false) String symbol) {
        ArrayList<BooleanExpression> booleanExpressions = new ArrayList<>();
        QExchangeCoin qExchangeCoin = QExchangeCoin.exchangeCoin;
        booleanExpressions.add(qExchangeCoin.enable.eq(1));
        if (StringUtils.isNotBlank(symbol)) {
            booleanExpressions.add(qExchangeCoin.baseSymbol.equalsIgnoreCase(symbol));
        }
        Predicate predicate = PredicateUtils.getPredicate(booleanExpressions);
        return R.ok(exchangeCoinRepository.findAll(predicate,null), 0);
    }

    @ApiOperation(value = "获取持仓明细")
    @GetMapping(value = "/query/pend")
    public R getWarehouseInfo(WarehouseQO page) {
        String url = adminUrl + "/system/member/wallet/warehouse?";
        StringBuffer stringBuffer = new StringBuffer(url);
        entitySuperclassToUrlParam(page, WarehouseQO.class, stringBuffer);
        return restTemplate.getForEntity(stringBuffer.toString(), R.class).getBody();
    }


    @ApiOperation(value = "获取挂单明细")
    @GetMapping(value = "/getPendingOrder")
    public R getPendingOrder(PendingOrderQO page) {
        String url = adminUrl + "/system/order/query/pend?";
        StringBuffer stringBuffer = new StringBuffer(url);
        entitySuperclassToUrlParam(page, PendingOrderQO.class, stringBuffer);
        return restTemplate.getForEntity(stringBuffer.toString(), R.class).getBody();
    }


    @ApiOperation(value = "交易汇总查询")
    @GetMapping(value = "/getTradeDetail")
    public R getTransactionSummary(CoinBalanceQO page) {
        String url = adminUrl + "/system/history/query/trade?";
        StringBuffer stringBuffer = new StringBuffer(url);
        entitySuperclassToUrlParam(page, CoinBalanceQO.class, stringBuffer);
        return restTemplate.getForEntity(stringBuffer.toString(), R.class).getBody();
    }


    public static <T> void entitySuperclassToUrlParam(T t, Class clazz, StringBuffer urlParam) {
        if (t == null || urlParam == null) {
            return;
        }
        //如果实体类对象为Object类型，则不处理
        if (!clazz.equals(Object.class)) {
            //获取实体类对象下的所有成员，并保存到 URL 参数存储器中
            Arrays.stream(clazz.getDeclaredFields()).forEach(field -> {
                //设置可以操作私有成员
                field.setAccessible(true);
                try {
                    //获取成员值
                    Object value = field.get(t);
                    //成员值为 Null 时，则不处理
                    if (Objects.nonNull(value)) {
                        urlParam.append(field.getName()).append("=").append(value).append("&");
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            });
            clazz = clazz.getSuperclass();
            //递归调用，获取父类的处理结果
            entitySuperclassToUrlParam(t, clazz, urlParam);
        }

    }


    /**
     * 交易所买卖的已成交数量，不算挂冻结单数量
     */
    @GetMapping(value = "/getTradeAmount")
    public R getTradeAmount(@RequestHeader("Authorization")String token,@RequestParam(name = "coin") String coin) {
        if (!this.token.equalsIgnoreCase(token)){
            return R.fail();
        }
        BigDecimal balance = exchangeOrderMapper.getTradeAmount(DateUtil.getDate() + " 00:00:00", coin);
        return R.ok(balance);
    }



    /**
     * 交易所买卖Aleo的已成交数量，不算挂冻结单数量
     */
    @GetMapping(value = "/getPlatformBalance")
    public R getAleoBalance(@RequestHeader("Authorization")String token,@RequestParam(name = "coin") String coin) {
        if (!this.token.equalsIgnoreCase(token)){
            return R.fail();
        }
        BigDecimal balance = memberWalletMapper.getPlatformBalance(coin);
        return R.ok(balance);
    }

}
